package com.pussinboots.morning.sync.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.pussinboots.morning.sync.dao.ErpProductViewMapper;
import com.pussinboots.morning.sync.dao.ProductMapper;
import com.pussinboots.morning.sync.entity.*;
import com.pussinboots.morning.sync.service.*;
import com.pussinboots.morning.sync.util.SyncUtil;
import lombok.extern.apachecommons.CommonsLog;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by TaoShuai on 2019/9/22.
 */
@Service
@Slf4j
public class SyncServiceImpl implements ISyncService {
    @Autowired
    private IErpMorningOrderWritebackService morningOrderWritebackService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IErpProductViewService productViewService;
    @Autowired
    private ErpProductViewMapper erpProductViewMapper;
    @Autowired
    private IProductService productService;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private IProductCategoryService productCategoryService;
    @Autowired
    private IProductAttributeService attributeService;
    @Autowired
    private IProductShadowService productShadowService;

    @Override
    public void syncOrder() {
        val orderWriteBackList = morningOrderWritebackService.getOrderWriteBack();
        if (orderWriteBackList == null || orderWriteBackList.isEmpty()) {
            log.warn("订单中间表没有可同步的数据");
            return;
        }
        val orderNumbers = new ArrayList<Long>();
        val orderList = new ArrayList<Order>();
        val orderList_ = new ArrayList<Order>();
        Order order;
        for (ErpMorningOrderWriteback morningOrderWriteback : orderWriteBackList) {
            order = Order.builder()
                    .orderNumber(morningOrderWriteback.getOrderNumber())
                    .orderStatus(morningOrderWriteback.getStatus())
                    .build();
            orderList.add(order);
            orderList_.add(order);
            orderNumbers.add(morningOrderWriteback.getOrderNumber());
        }

        /*val orderNumbers_ = orderService.getOrderNumbersByOrderNumbers(orderNumbers);
        if (orderNumbers_ == null || orderNumbers_.isEmpty()) {
            return;
        }*/

        /*if (orderNumbers_.size() != orderNumbers.size()) {
            val diff = SyncUtil.getDiffrent(orderNumbers, orderNumbers_);
            // TODO 打印日志，diff里包含了ERP中有但药事汇里没有的订单
            // 移除药事汇中没有的订单
            for (Long num : diff) {
                for (Order order_ : orderList) {
                    if (order_.getOrderNumber() == num) {
                        orderList_.remove(order_);
                        orderNumbers.remove(num);
                    }
                }
            }
        }*/
        orderService.changeBatchOrderStatusByOrderNumber(orderList_);
        morningOrderWritebackService.execWriteBack(orderNumbers);
    }

    @Override
    // @Transactional(rollbackFor = Exception.class)
    public void syncStockOrProduct(boolean isSyncProduct) {
        log.info("---------开始同步药事汇商品信息---------");
        long startTime = System.currentTimeMillis();
        try {
            List<Product> productList = productService.list(new QueryWrapper<Product>().select("erp_id, product_id, status"));
            List<ErpProductView> erpProductViewList = productViewService.list(new QueryWrapper<ErpProductView>()/*.le("rownum", 2)*/);
            if (erpProductViewList == null || erpProductViewList.isEmpty()) {
                log.warn("ERP商品视图（v_ysh_spjg）未发现需要同步的数据");
                return;
            }
            log.info("ERP商品视图（v_ysh_spjg）中总共有{}条记录", erpProductViewList.size());
            List<Map> morningErpIds = new ArrayList<>();
            List<Map> erpIds = new ArrayList<>();
            List<Long> needDeletedProductIds = new ArrayList<>();
            for (Product product : productList) {
                if (product==null || (product.getStatus()!=-1 && (product.getErpId() == null || "".equals(product.getErpId())))) {
                    // 用来存储无erpId的记录，也就是要逻辑删除的记录
                    needDeletedProductIds.add(product.getProductId());
                    continue;
                }
                Map proMap = new HashMap();
                /*if (product.getErpId().equals("d037009")) {
                    System.out.println("product d037009===>" + product.toString());
                }*/
                proMap.put("erpId", product.getErpId());
                proMap.put("status", product.getStatus());
                morningErpIds.add(proMap);
            }
            for (ErpProductView erpProduct : erpProductViewList) {
                /*if (erpProduct.getErpId().equals("d037009")) {
                    System.out.println("erpProduct d037009===>" + erpProduct.toString());
                }*/
                Map erpMap = new HashMap();
                erpMap.put("erpId", erpProduct.getErpId());
                erpMap.put("status", 1);
                erpIds.add(erpMap);
            }
            Map<String, List<String>> diffMap = SyncUtil.breakUpList(morningErpIds, erpIds);
            syncProdcutDetail(diffMap, erpProductViewList, needDeletedProductIds, isSyncProduct);
            log.info("---------结束同步药事汇商品表，共消耗{}秒---------", (System.currentTimeMillis() - startTime) / 1000D);
        } catch (Exception e) {
            log.error("×××××××××同步出错，错误信息：{}×××××××××", e.getMessage(), e);
        }
    }

    private void syncProdcutDetail(Map<String, List<String>> diffMap, List<ErpProductView> erpList, List<Long> needDeletedProductIds, boolean isSyncProduct) {
        // 要删除的 (erpId作为标记)
        List<String> productDiff = diffMap.get("list1Diff");
        // 要新增的 (erpId作为标记)
        List<String> erpProductDiff = diffMap.get("list2Diff");
        // 要更新的 (erpId作为标记)
        List<String> theSameList = diffMap.get("sameList");

        Integer deleteCount = 0, updateCount = 0, insertCount = 0;
        try {
            /**
             * 执行批量删除
             */
            // 删除erp_id在ERP表没有的商品记录
            if (productDiff != null && !productDiff.isEmpty()) {
                if (isSyncProduct) {
                    // 批量删除商品（其实是设置status = -1）
                    productService.update(new UpdateWrapper<Product>().setSql(true,"status = -1").in("erp_id", productDiff));
                    /*// 批量删除与分类的关联
                    productCategoryService.delCategoryByErpId(productDiff);
                    // 批量删除库存（因为库存是跟着商品来的，不可能撇去商品自己删除）
                    attributeService.delStockByErpId(productDiff);*/
                }

                deleteCount += productDiff.size();
            }
            // 删除erp_id为空的商品记录
            if (needDeletedProductIds != null && !needDeletedProductIds.isEmpty()) {
                if (isSyncProduct) {
                    // 批量删除商品（其实是设置status = -1）
                    productService.update(new UpdateWrapper<Product>().setSql(true,"status = -1").in("product_id", needDeletedProductIds));
                    /*// 批量删除与分类的关联
                    productCategoryService.remove(new QueryWrapper<ProductCategory>().in("product_id", needDeletedProductIds));
                    // 批量删除库存（因为库存是跟着商品来的，不可能撇去商品自己删除）
                    attributeService.remove(new QueryWrapper<ProductAttribute>().in("product_id", needDeletedProductIds));*/

                    deleteCount += needDeletedProductIds.size();
                }
            }
            if (isSyncProduct) {
                log.info("逻辑删除{}条：【药事汇商品表(os_prduct)】", deleteCount);
                log.info("逻辑删除{}条：【药事汇商品-分类关联表(os_prduct_category)】", deleteCount);
                log.info("逻辑删除{}条：【药事汇库存表(os_prduct_attribute)】", deleteCount);
            }


            // 按需要新增的和需要更新的拆分List
            Map<String, List<ErpProductView>> erpMap = SyncUtil.breakUpErpList(erpList, theSameList, erpProductDiff);
            List<ErpProductView> updateList = erpMap.get("updateList");
            List<ErpProductView> insertList = erpMap.get("insertList");

            /**
             * 执行批量新增
             */
            if (insertList != null && !insertList.isEmpty()) {
                List<Product> insertProductList = SyncUtil.transformList(insertList);
                if (isSyncProduct) {
                    productService.saveBatch(insertProductList);

                    val productCategories = new ArrayList<ProductCategory>();
                    val attributes = new ArrayList<ProductAttribute>();
                    val onlineShadows = new ArrayList<ProductShadow>();
                    val offlineShadows = new ArrayList<ProductShadow>();
                    ProductCategory productCategory;
                    ProductAttribute attribute;
                    ProductShadow onlineProductShadow;
                    ProductShadow offlineProductShadow;
                    for (Product product : insertProductList) {
                        if (product.getProductId() != null) {
                            productCategory = ProductCategory.builder().categoryId(1071L).productId(product.getProductId()).build();
                            productCategories.add(productCategory);

                            attribute = ProductAttribute.builder()
                                    .stock(product.getStock())
                                    .productId(product.getProductId())
                                    .erpId(product.getErpId())
                                    .build();
                            attributes.add(attribute);

                            onlineProductShadow = ProductShadow.builder()
                                    .productId(product.getProductId())
                                    .userId(91L)
                                    .build();
                            onlineShadows.add(onlineProductShadow);
                            offlineProductShadow = ProductShadow.builder()
                                    .productId(product.getProductId())
                                    .userId(94L)
                                    .build();
                            offlineShadows.add(offlineProductShadow);
                        }
                    }
                    //创建商品副本（线上、线下各一份）
                    productShadowService.saveBatch(onlineShadows);
                    productShadowService.saveBatch(offlineShadows);
                    // 批量新增默认分类
                    productCategoryService.saveBatch(productCategories);
                    // 批量新增库存（因为库存是跟着商品来的，不可能撇去商品自己新增）
                    attributeService.saveBatch(attributes);

                    insertCount += insertProductList.size();
                }

            }
            if (isSyncProduct) {
                log.info("新增{}条：【药事汇商品表(os_prduct)】", insertCount);
                log.info("新增{}条：【药事汇商品-分类关联表(os_prduct_category)】", insertCount);
                log.info("新增{}条：【药事汇库存表(os_prduct_attribute)】", insertCount);
            }

            /**
             * 执行批量更新
             */
            if (updateList != null && !updateList.isEmpty()) {
                List<Product> updateProductList = SyncUtil.transformList(updateList);
                if (isSyncProduct) {
                    productService.updateBatchByErpId(updateProductList);
                }
                // 批量更新库存
                attributeService.updateBatchByProduct(updateProductList);
                updateCount += updateProductList.size();
            }
            if (isSyncProduct) {
                log.info("更新{}条：【药事汇商品表(os_prduct)】", updateCount);
            }
            log.info("更新{}条：【药事汇库存表(os_prduct_attribute)】", updateCount);

            int syncProductCount =  updateCount;
            int syncCateGoryCount = deleteCount + insertCount;
            if (isSyncProduct) {
                log.info("统计：本次同步【药事汇商品表(os_prduct)】共{}条数据，【药事汇商品-分类关联表(os_prduct_category)】共{}条数据，【药事汇库存表(os_prduct_attribute)】共{}条数据",
                        syncProductCount, syncCateGoryCount, syncProductCount);
            } else {
                log.info("统计：本次同步【药事汇库存表(os_prduct_attribute)】共{}条数据", syncProductCount);
            }


        } catch (Exception e) {
            log.error("×××××××××同步出错，错误信息：{}×××××××××", e.getMessage(), e);
        }

    }
}
